<template>
<!-- Vue3组件中的模板结构中可以没有根标签 -->
<h1>一个人的信息</h1>
<h2>1姓名：{{person.name}}</h2>
<h2>年龄: {{person.age}}</h2>
<h3>工作种类: {{person.job.type}}</h3>
<h3>工作薪水: {{person.job.salary}}</h3>
<h3>测试的数据c:{{person.a.b.c}}</h3>
<h3>爱好：{{person.hobby}}</h3>
<button @click="changeInfo">更改人的信息</button>
<Demo @hello="showHelloMsg"  school="尚硅谷" msg="我是">
  <span>杉菜酱，你好！</span>
  <template v-slot:ykMsg>
    <div>云梦无羡，你好！</div>
  </template>
</Demo>
<span>这是sum的值:{{sum}}</span>
</template>

<script>
import {reactive, ref, watch, watchEffect} from 'vue'
import {computed} from 'vue'
import Demo from './components/Demo.vue'
export default {
  name: 'App',
  components:{
    Demo
  },
  setup(){
    // 数据    ref函数处理基本类型
    let name = ref('张三')
    let age = ref(18)
    let sum = ref(355)
    // ref函数处理对象类型
    let job = reactive({
      type:'前端工程师',
      salary: '30k',
      a:{
        b:{
          c:666
        }
      }
    })
    let hobby = reactive(['抽烟','喝酒','烫头'])
  
    let person = reactive({ 
      name: '张三',
      firstName:'杉菜酱子',
      lastName:'云梦无羡',
      age : 18,
      a:{
          b:{
            c:666
          }
        },
        // ref函数处理对象类型
        job : {
          type:'前端工程师',
          salary: '30k',
          // let hobby = ['抽烟','喝酒','烫头']
          
      },
      hobby : ['抽烟','喝酒','烫头']
    })
    // 方法
    function changeInfo(){
      // name.value = '李四'
      // age.value = 48
      // console.log(name,age);  // RefImpl 引用实现的实例对象（引用对象）
      // console.log(job);  // Proxy代理对象
      // job.type = '后端开发'
      // job.salary = '50k',
      // job.a.b.c = 888   // 可以修改，说明reactive处理对象是深层次的
      // hobby[0] = '学习'
      person.age = 80
      person.job.salary = '90k'
      person.job.type = '测试'
      person.hobby = ['学习']
      person.name = '小明'
      person.a.b.c = '7777'
      person.firstName = '杰西'
      person.lastName = '卡尔'
      age.value = 777
      sum.value = 999
    }
    function showHelloMsg(value){
      sum.value = 9999
      alert(`你好啊，你触发了hello事件，我收到的参数是：${value}`)
    }
    // 计算属性

    // 计算属性 ———— 简写
    let fullname = computed(()=>{
      return person.firstName + '-' + person.lastName
    })
    // 计算属性 ———— 完整
    let fullname1 = computed({
      get(){
        return person.firstName + '-' + person.lastName
      },
      set(value){
        const nameArr = value.split('-')
        person.firstName = nameArr[0]
        person.lastName = nameArr[1]
      }
    })
    // watch 函数   监视数据
    // 情况一: 监视ref定义的响应式数据
    watch(sum,(newValue,oldValue)=>{
        console.log('sum变化了',newValue,oldValue);
    },{immediate:true}) 
    // 如果用ref定义了一个对象
    watch(person,(newValue,oldValue)=>{
      console.log('person变化了',newValue,oldValue);  // oldValue 无法正确获取
    },{deep:true})
    // 情况二：监视多个ref定义的响应式数据
    watch([sum,age],(newValue,oldValue) => {
        console.log('sum或age变化了',newValue,oldValue);
    }) 
    // 情况三：监视reactive定义的响应式数据
      // 若watch监视的是reactive定义的响应式数据，则无法正确获得oldValue
      // 若watch监视的是reactive定义的响应式数据，则强制开启了深度监视
      watch(person,(newValue,oldValue)=>{
        console.log('person变化了',newValue,oldValue)
      },{immediate:true,deep:false}) //此处的deep配置不再奏效
    // 情况四：监视reactive定义的响应式数据中的某个属性   但是无法获得正确的oldValue
    watch(()=>person.job,(newValue,oldValue)=>{
        console.log('person的job变化了',newValue,oldValue);
    },{immediate:true,deep:true})
    // 情况五：监视reactive定义的响应式数据中的某些属性
    watch([()=>person.job,()=>person.name],(newValue,oldValue)=>{
      console.log('person的job变化了',newValue,oldValue);
    },{immediate:true,deep:true})
    // watchEffect 所指定的回调中用到的数据只要发生变化，则重新执行回调。
    watchEffect(()=>{
      const x1 = sum.value
      const x2 = person.age 
      console.log('watchEffect配置的回调执行了');
    })
    // 可以返回一个对象（常用）
    return {
      // name,
      // age,
      // job,
      hobby,
      changeInfo,
      person,
      showHelloMsg,
      sum
    }
  }
}
</script>

<style>
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
</style>
